﻿using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace Jinndev {

    //[System.Obsolete("实现的不好")]
    public static class StorageUtill {

        public static bool Initialized { get; private set; }
        private static string root = null;

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="locateBuildInEditor">在编辑器模式，是否对应到Build目录</param>
        public static void Init(bool locateBuildInEditor) {
            if (Initialized) {
                return;
            }
            string projectPath = new DirectoryInfo(Application.dataPath).Parent.FullName;
            string productName = Application.productName;

            if (Application.isEditor && locateBuildInEditor) {
                if (Directory.Exists(Path.Combine(projectPath, "Build", productName))) {
                    root = Path.Combine(projectPath, "Build", productName, "Storage");
                }
                else if (File.Exists(Path.Combine(projectPath, "Build", productName + ".exe"))) {
                    root = Path.Combine(projectPath, "Build", "Storage");
                }
            }

            if (root == null) {
                root = Path.Combine(projectPath, "Storage");
            }
            if (!Directory.Exists(root)) {
                Directory.CreateDirectory(root);
            }

            //Debug.Log("Storage path: " + root);
            Initialized = true;
        }

        public static string GetStoragePath(string path) {
            return Path.Combine(GetStoragePath(), path);
        }

        public static string GetStoragePath() {
            if (!Initialized) {
                throw new System.InvalidOperationException("Need initializion");
            }
            return root;
        }

        public static string PrepairDir(string dir) {
            string path = Path.Combine(GetStoragePath(), dir);
            if (!Directory.Exists(path)) {
                Directory.CreateDirectory(path);
            }
            return path;
        }

        public static bool Exists(string path) {
            return File.Exists(Path.Combine(GetStoragePath(), path));
        }

        public static void Delete(string path) {
            File.Delete(Path.Combine(GetStoragePath(), path));
        }

        public static long Length(string path) {
            FileInfo info = new FileInfo(Path.Combine(GetStoragePath(), path));
            if (info.Exists) {
                return info.Length;
            }
            return 0;
        }

        public static void WriteBytes(string path, byte[] bytes) {
            File.WriteAllBytes(Path.Combine(GetStoragePath(), path), bytes);
        }

        public static void WriteText(string path, string text, Encoding encoding) {
            File.WriteAllText(Path.Combine(GetStoragePath(), path), text, encoding == null ? Encoding.UTF8 : encoding);
        }

        public static void WriteObject(string path, object obj) {
            MemoryStream ms = SerializeBinary(obj);
            WriteBytes(path, ms.GetBuffer());
        }

        public static byte[] ReadBytes(string path) {
            return File.ReadAllBytes(Path.Combine(GetStoragePath(), path));
        }

        public static string ReadText(string path, Encoding encoding = null) {
            return File.ReadAllText(Path.Combine(GetStoragePath(), path), encoding == null ? Encoding.UTF8 : encoding);
        }

        public static T ReadObject<T>(string path) where T : class {
            byte[] bytes = ReadBytes(path);
            return DeSerializeBinary(bytes) as T;
        }

        public static object DeSerializeBinary(byte[] bytes) {
            if (bytes == null) {
                return null;
            }
            return DeSerializeBinary(new MemoryStream(bytes));
        }

        public static object DeSerializeBinary(MemoryStream memStream) {
            memStream.Position = 0;
            BinaryFormatter deserializer = new BinaryFormatter();
            object newobj = deserializer.Deserialize(memStream);
            memStream.Close();
            return newobj;
        }

        public static MemoryStream SerializeBinary(object request) {
            BinaryFormatter serializer = new BinaryFormatter();
            MemoryStream memStream = new MemoryStream();
            serializer.Serialize(memStream, request);
            return memStream;
        }

    }

}
